#include<iostream>
#include<memory>
#include<string>

//建造者模式
//电脑抽象类
class Computer
{
    public:
        using ptr = std::shared_ptr<Computer>; //typedef std::shared_ptr<Computer> ptr
        Computer(){}
        void set_board(const std::string& board) {_board = board;}
        void set_display(const std::string& display) {_display = display;}
        virtual void set_os() = 0;
        void Exhibit()
        {
            std::cout<<"Computer:\n";
            std::cout<<"\tboard : "<<_board<<std::endl;
            std::cout<<"\tdisplay : "<<_display<<std::endl;
            std::cout<<"\tos : "<<_os<<std::endl;
        }
    protected:
        std::string _board; //主板
        std::string _display;   //显示屏
        std::string _os;    //操作系统
};

//电脑派生类
class MacBook : public Computer
{
    public:
        using ptr = std::shared_ptr<MacBook>;
        virtual void set_os()
        {
            _os = "Mac os X12";
        }
};

//建造者抽象类
class Builder
{
    public:
        using ptr = std::shared_ptr<Builder>;
        virtual void build_board(const std::string& board) = 0;
        virtual void build_display(const std::string& display) = 0;
        virtual void build_os() = 0;
        virtual Computer::ptr build() = 0;
};

//派生建造者类--实现对应的接口方法
class ComputerBuilder : public Builder
{
    public:
        using ptr = std::shared_ptr<ComputerBuilder>;
        ComputerBuilder():_computer(new MacBook()){}
        virtual void build_board(const std::string& board) {_computer->set_board(board);}
        virtual void build_display(const std::string& display) {_computer->set_display(display);}
        virtual void build_os() {_computer->set_os();}
        virtual Computer::ptr build() {return _computer;}
    private:
        Computer::ptr _computer;
};

//指挥者类--对建造顺序进行指挥
class Director
{
    public:
    Director(Builder* builder):_builder(builder){}
    void construct(const std::string& board,const std::string& display)
    {
        _builder->build_board(board);
        _builder->build_display(display);
        _builder->build_os();
    }
    private:
    Builder::ptr _builder; 
};

int main()
{
    Builder* builder = new ComputerBuilder();
    std::shared_ptr<Director> director(new Director(builder));
    director->construct("华硕B760M-P","Samsung Odyssey G9 49");
    Computer::ptr cp = builder->build();
    cp->Exhibit();
    return 0;
}